//
//  LBLoopScrollView.m
//  LBLoopScrollView
//
//  Created by LINAICAI on 2017/6/5.
//  Copyright © 2017年 LINAICAI. All rights reserved.
//

#import "LBLoopScrollView.h"
#import "LBLoopScrollViewCell.h"
#import "NSTimer+LBLoopScrollView.h"
#import <SDWebImage/UIImageView+WebCache.h>
#import <LBCoreKit/LBPrefix.h>
#import <LBCoreKit/LBUtils.h>
#import <LBCategory/NSString+LBString.h>
static NSString * const kCellID = @"identity";
static CGFloat  const kPageControlHeight = 40;
@interface LBLoopScrollView()<UICollectionViewDelegate,UICollectionViewDataSource,UIScrollViewDelegate,UICollectionViewDelegateFlowLayout>
@property (nonatomic , strong)UICollectionViewFlowLayout *layout;
@property (nonatomic , strong)UICollectionView *collectionView;

//当前位置
@property (nonatomic , assign)NSInteger currentPage;
@property (nonatomic , strong)NSTimer *timer;
//数据源中使用的
@property (nonatomic , strong)NSArray *dataSources;
@end
@implementation LBLoopScrollView
#pragma mark- Getting
- (UICollectionViewScrollPosition)scrollPosition{
    if (_direction == LBLoopScrollViewDirectionLeft) {
        return UICollectionViewScrollPositionLeft;
    }
    else if (_direction == LBLoopScrollViewDirectionRight){
        return UICollectionViewScrollPositionRight;
    }
    else if (_direction == LBLoopScrollViewDirectionUp){
        return UICollectionViewScrollPositionTop;
    }
    else if (_direction == LBLoopScrollViewDirectionDown){
        return UICollectionViewScrollPositionBottom;
    }
    return UICollectionViewScrollPositionNone;
}
- (void)processingData{
    if (self.originSources.count == 0) {
        return;
    }
    //只有一个数据的时候不必滚动
    if (self.originSources.count == 1) {
        self.dataSources = [NSArray arrayWithArray:self.originSources];
    }
    else{
        //满足数据要求，处理滚动数据源
        NSMutableArray *array = [NSMutableArray arrayWithArray:self.originSources];
        //在末尾添加第一个数据
        [array addObject:self.originSources.firstObject];
        //在头部添加最后一个数据
        [array insertObject:self.originSources.lastObject atIndex:0];
        self.dataSources = array;
    }
    _pageControl.numberOfPages = self.originSources.count;
    _pageControl.hidden = !_showPageControl;
}
- (NSArray *)dataSources{
    if (!_dataSources) {
        _dataSources = [NSArray new];
    }
    return _dataSources;
}
- (UIPageControl *)pageControl{
    if (!_pageControl) {
        _pageControl = [[UIPageControl alloc]init];
        _pageControl.defersCurrentPageDisplay = YES;
        _pageControl.hidesForSinglePage = YES;
        [_pageControl setPageIndicatorTintColor:[UIColor whiteColor]];
        [_pageControl setCurrentPageIndicatorTintColor:[UIColor blackColor]];
        _pageControl.numberOfPages = self.originSources.count;
    }
    return _pageControl;
}
- (UICollectionViewFlowLayout *)layout{
    if (!_layout) {
        _layout = [[UICollectionViewFlowLayout alloc]init];
        _layout.minimumLineSpacing = 0;
        _layout.minimumInteritemSpacing = 0;
        _layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    }
    return _layout;
}
- (UICollectionView *)collectionView{
    if (!_collectionView) {
        _collectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:self.layout];
        _collectionView.delegate = self;
        _collectionView.dataSource = self;
        _collectionView.pagingEnabled = YES;
        _collectionView.scrollEnabled = YES;
        _collectionView.showsVerticalScrollIndicator = NO;
        _collectionView.showsHorizontalScrollIndicator = NO;
        _collectionView.backgroundColor = [UIColor whiteColor];
        [_collectionView registerClass:[LBLoopScrollViewCell class] forCellWithReuseIdentifier:kCellID];
        
    }
    return _collectionView;
}
#pragma mark- 初始化方法
- (instancetype)init
{
    return [self initWithFrame:CGRectZero images:nil];
}
- (instancetype)initWithimages:(NSArray *)images{
    return [self initWithFrame:CGRectZero images:images];
}
- (instancetype)initWithFrame:(CGRect)frame
{
    return [self initWithFrame:frame images:nil];
}
- (instancetype)initWithFrame:(CGRect)frame images:(NSArray *)images
{
    self = [super initWithFrame:frame];
    if (self) {
        _originSources = images;
        [self initialize];
    }
    return self;
}
#pragma mark- 初始化方法
- (void)initialize
{
    [self configDefault];
    [self addSubview:self.collectionView];
    [self addSubview:self.pageControl];
    [self reload];
    [self prepareDisplay];
}
- (void)reload{
    [self processingData];
    [self.collectionView reloadData];
    
    if (self.pageControl.numberOfPages == 0) {
        return;
    }
    //如果只有一个数据
    if (self.pageControl.numberOfPages == 1) {
        [self removeTimer];
        self.pageControl.currentPage = 0;
        self.currentPage = self.pageControl.currentPage +1 ;
        NSIndexPath *idxPath = [NSIndexPath indexPathForItem:0 inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
    }
    else{
        [self addTimer];
        self.pageControl.currentPage = 0;
        self.currentPage = self.pageControl.currentPage + 1;
        NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
    }
    [self prepareDisplay];
}
- (void)configDefault{
    //默认配置
    self.direction = LBLoopScrollViewDirectionLeft;
    self.automatically = NO;
    self.showPageControl = YES;
    self.timeInterval = 1.0;
}
#pragma mark- Setting
- (void)setOriginSources:(NSArray *)originSources{
    //一旦修改数据源，需要同时修改很多地方
    _originSources = originSources;
    [self reload];
}
- (void)setTimeInterval:(NSTimeInterval)timeInterval{
    _timeInterval = timeInterval;
    [self reload];
}
- (void)setAutomatically:(BOOL)automatically{
    _automatically = automatically;
    [self reload];
}
- (void)setShowPageControl:(BOOL)showPageControl{
    _pageControl.hidden =  !(_showPageControl = showPageControl);
    [self reload];
}
- (void)setDirection:(LBLoopScrollViewDirection)direction{
    _direction = direction;
    if (_direction == LBLoopScrollViewDirectionUp || _direction == LBLoopScrollViewDirectionDown) {
        self.layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    }
    else{
        self.layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    }
    [self reload];
}

#pragma mark- 重写方法
- (void)dealloc{
    [self removeTimer];
    self.delegate = nil;
}
- (void)layoutSubviews{
    [super layoutSubviews];
    self.collectionView.frame = self.bounds;
    self.pageControl.frame = CGRectMake(0, self.bounds.size.height-kPageControlHeight, self.bounds.size.width, kPageControlHeight);
    if (self.originSources.count > 1) {
        NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
    }

}
#pragma mark 定时器操作
-(void) addTimer{
    //数据太少的时候就不必启动定时器
    if (self.pageControl.numberOfPages == 1) {
        return;
    }
    //需要定时器驱动的时候
    if (self.automatically) {
        [self removeTimer];
        __weak LBLoopScrollView *weakSelf = self;
        self.timer =  [NSTimer lb_scheduledTimerWithTimeInterval:_timeInterval repeats:YES target:self timerBlock:^(id sender) {
            [weakSelf nextPage];
        }];
    }
    else{
        //这里为了防止self.automatically由YES改为NO后计时器还会跑的情况，所以需要移除
        [self removeTimer];
    }
}
-(void) removeTimer{
    if (self.automatically) {
        //invalidate方法的作用是把他从NSRunloop中移除
        if ([self.timer isValid]) {
            [self.timer invalidate];
        }
        self.timer = nil;
    }
}
#pragma mark- 水平方向滚动
- (void)goToLeftPage{
    if (self.currentPage >= (self.originSources.count)) {
        //如果当前页面达到最后一个,[4 1 2 3 4 1]中的第二个4，偷偷移到第一个位置，[4 1 2 3 4 1]中的第一个4，再接着滚动一次即可。
        
        //偷偷移动
        self.currentPage = 0;
        NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:NO];
    }
    self.currentPage++;
    NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
    [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:YES];
    self.pageControl.currentPage = self.currentPage-1;
    
}

- (void)goToRightPage{
    //如果当前页面达到第一个,[4 1 2 3 4 1]中的第一个1，偷偷移到第一个位置，[4 1 2 3 4 1]中的第二个1，再接着滚动一次即可。
    if (self.currentPage <= 1) {
        //偷偷移动
        self.currentPage = self.originSources.count+1 ;
        NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:NO];
    }
    self.currentPage--;
    NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
    [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:YES];
    self.pageControl.currentPage = self.currentPage-1;
    
}
#pragma mark- 垂直方向滚动
- (void)goToUpPage{
    if (self.currentPage >= (self.originSources.count)) {
        //如果当前页面达到最后一个,[4 1 2 3 4 1]中的第二个4，偷偷移到第一个位置，[4 1 2 3 4 1]中的第一个4，再接着滚动一次即可。
        
        //偷偷移动
        self.currentPage = 0;
        NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:NO];
    }
    self.currentPage++;
    NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
    [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:YES];
    self.pageControl.currentPage = self.currentPage-1;
    NSLog(@"当前页面=%ld",(long)self.pageControl.currentPage);
}

- (void)goToDownPage{
    //如果当前页面达到第一个,[4 1 2 3 4 1]中的第一个1，偷偷移到第一个位置，[4 1 2 3 4 1]中的第二个1，再接着滚动一次即可。
    if (self.currentPage <= 1) {
        //偷偷移动
        self.currentPage = self.originSources.count+1 ;
        NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:NO];
    }
    self.currentPage--;
    NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
    [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:YES];
    self.pageControl.currentPage = self.currentPage-1;
    
}
- (NSInteger)pageWithScrollView:(UIScrollView *)scrollView{
    NSInteger page;
    if (_direction == LBLoopScrollViewDirectionLeft || _direction == LBLoopScrollViewDirectionRight) {
        CGFloat pageWidth = scrollView.frame.size.width;
        page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    }
    else{
        CGFloat pageHeight = scrollView.frame.size.height;
        page = floor((scrollView.contentOffset.y - pageHeight / 2) / pageHeight) + 1;
    }
    NSLog(@"page=%ld",page);
    return page;
}


- (void)nextPage{
    if (_direction == LBLoopScrollViewDirectionLeft) {
        [self goToLeftPage];
    }
    else if (_direction == LBLoopScrollViewDirectionRight){
        [self goToRightPage];
    }
    else if (_direction == LBLoopScrollViewDirectionUp){
        [self goToUpPage];
    }
    else if (_direction == LBLoopScrollViewDirectionDown){
        [self goToDownPage];
    }
    if (self.delegate && [self.delegate respondsToSelector:@selector(LBLoopScrollViewChageCurrentPageWithIndex:)]) {
        [self.delegate LBLoopScrollViewChageCurrentPageWithIndex:self.pageControl.currentPage];
    }
    
}
#pragma mark- 可重写的方法
//针对子类如果想修改或者添加视图可以在这个方法中添加和修改，但请切记不要主动调用该方法，因为没必要
- (void)prepareDisplay{
    
}
#pragma mark- UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    if (self.delegate && [self.delegate respondsToSelector:@selector(LBLoopScrollViewDidClickWithIndex:)]) {
        [self.delegate LBLoopScrollViewDidClickWithIndex:self.pageControl.currentPage];
    }
}
#pragma mark- UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return self.dataSources.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    LBLoopScrollViewCell *cell = (LBLoopScrollViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];
    if (!cell) {
        cell = [[LBLoopScrollViewCell alloc]init];
    }
    
    [cell.imageView sd_setImageWithURL:LBIMAGEURL(self.dataSources[indexPath.item])];
    return cell;
}
#pragma mark 当用户停止的时候调用
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
    [self addTimer];
    NSLog(@"开始定时器");
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{    //拖动前的起始坐标
    [self removeTimer];
    NSLog(@"移除定时器");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    //如果只有一张图片，不起作用
    if (self.pageControl.numberOfPages == 1) {
        return;
    }
    NSInteger page = [self pageWithScrollView:scrollView];
    if (page == 0) {
        //滚动到左边
        self.pageControl.currentPage =self.currentPage = self.dataSources.count - 2;
        NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.currentPage inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:NO];
    }else if (page == self.dataSources.count - 1){
        //滚动到右边的时候偷偷移动
        self.pageControl.currentPage =self.currentPage = 0;
        NSIndexPath *idxPath = [NSIndexPath indexPathForItem:1 inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:[self scrollPosition] animated:NO];
    }else{
        self.pageControl.currentPage = self.currentPage = page - 1;
    }
    if (self.delegate && [self.delegate respondsToSelector:@selector(LBLoopScrollViewChageCurrentPageWithIndex:)]) {
        [self.delegate LBLoopScrollViewChageCurrentPageWithIndex:self.pageControl.currentPage];
    }
    NSLog(@"手动拖动后 self.currentPage=%ld",(long)self.currentPage);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    return self.bounds.size;
}
@end
